/*
 * Copyright (C) 2011 by ayoung <ayoung.p@gmail.com>
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.peaceb.ruletherain;

import java.util.ArrayList;

import android.app.Application;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteException;

public class RuleTheRainApplication extends Application {
    private Engine                 mEngine;
    private ArrayList<WeatherInfo> mCityList;
    private long                   mDatabaseModifiedTime;
    
    @Override
    public void onCreate() {
        super.onCreate();
        Trace.v(this, "onCreate");
        
        mCityList = new ArrayList<WeatherInfo>();
        loadCityList();
        mEngine = new Engine(this);
    }

    public Engine getEngine() {
        return mEngine;
    }
    
    /**
     * Load city list
     * 
     * @return
     */
    public int loadCityList() {
        mCityList.clear();
        
        addUserCityList(mCityList);
        mCityList.add(new WeatherInfo("Atlanta", 33.748995, -84.387982, 0));
        mCityList.add(new WeatherInfo("Bangkok", 13.723419, 100.476232, 0));
        mCityList.add(new WeatherInfo("Bangui", 4.361698, 18.555975, 0));
        mCityList.add(new WeatherInfo("Barter Island", 70.126669,-143.663435, 0));
        mCityList.add(new WeatherInfo("Belfast", 54.597269, -5.930109, 0));
        mCityList.add(new WeatherInfo("Bellingham", 48.759553, -122.488225, 0));
        mCityList.add(new WeatherInfo("Bergen", 60.391263, 5.322054, 0));
        mCityList.add(new WeatherInfo("Bioko", 3.619832, 8.748117, 0));
        mCityList.add(new WeatherInfo("Boston", 42.358431, -71.059773, 0));
        mCityList.add(new WeatherInfo("Buea", 4.155169, 9.231388, 0));
        mCityList.add(new WeatherInfo("Calcutta", 22.572646, 88.363895, 0));
        mCityList.add(new WeatherInfo("Cameroon", 7.369722, 12.354722, 0));
        mCityList.add(new WeatherInfo("Cherrapunji", 25.3, 91.7, 0));
        mCityList.add(new WeatherInfo("Colombia", 4.570868, -74.297333, 0));
        mCityList.add(new WeatherInfo("Colombo", 6.927079,79.861243, 0));
        mCityList.add(new WeatherInfo("Da Nang", 16.051571, 108.214897, 0));
        mCityList.add(new WeatherInfo("Daegu", 35.871435, 128.601445, 0));
        mCityList.add(new WeatherInfo("Dallas", 32.802955, -96.769923, 0));
        mCityList.add(new WeatherInfo("Dhaka", 23.709921, 90.407143, 0));
        mCityList.add(new WeatherInfo("Guadeloupe", 16.265, -61.551, 0));
        mCityList.add(new WeatherInfo("Hanoi", 21.033333, 105.85, 0));
        mCityList.add(new WeatherInfo("Hawaii", 19.896766, -155.582782, 0));
        mCityList.add(new WeatherInfo("Ho Chi Minh", 10.823099, 106.629664, 0));
        mCityList.add(new WeatherInfo("Hong Kong", 22.396428, 114.109497, 0));
        mCityList.add(new WeatherInfo("Honiara", -9.430384, 159.948323, 0));
        mCityList.add(new WeatherInfo("Iceland", 64.963051, -19.020835, 0));
        mCityList.add(new WeatherInfo("Juneau", 58.301944, -134.419722, 0));
        mCityList.add(new WeatherInfo("Kauai", 22.09644, -159.526124, 0));
        mCityList.add(new WeatherInfo("London", 51.500152, -0.126236, 0));
        mCityList.add(new WeatherInfo("Madrid", 40.416691, -3.700345, 0));
        mCityList.add(new WeatherInfo("Manchester", 53.480713, -2.234376, 0));
        mCityList.add(new WeatherInfo("Manila", 14.599512,120.98422, 0));
        mCityList.add(new WeatherInfo("Mawsynram", 25.3, 91.583333, 0));
        mCityList.add(new WeatherInfo("Miami", 25.788969, -80.226439, 0));
        mCityList.add(new WeatherInfo("Milan", 45.463681, 9.188171, 0));
        mCityList.add(new WeatherInfo("Montenegro", 42.708678, 19.37439, 0));
//        mCityList.add(new WeatherInfo("Moscow", 55.755786, 37.617633, 0)); // Not working
        mCityList.add(new WeatherInfo("Nairobi", -1.283333, 36.816667, 0));
        mCityList.add(new WeatherInfo("New Orleans", 29.951066, -90.071532, 0));
        mCityList.add(new WeatherInfo("New York", 40.714353, -74.005973, 0));
        mCityList.add(new WeatherInfo("Orlando", 28.538336, -81.379236, 0));
        mCityList.add(new WeatherInfo("Papua New Guinea", -6.314993, 143.95555, 0));
//        mCityList.add(new WeatherInfo("Paris", 48.856614, 2.352222, 0)); // Not working
        mCityList.add(new WeatherInfo("Phnom Penh", 11.558831, 104.917445, 0));
        mCityList.add(new WeatherInfo("Prague", 50.087811, 14.42046, 0));
        mCityList.add(new WeatherInfo("Quibdo", 5.7, -76.666667, 0));
        mCityList.add(new WeatherInfo("Sao Paulo", -23.548943, -46.638818, 0));
        mCityList.add(new WeatherInfo("Seattle", 47.60621, -122.332071, 0));
        mCityList.add(new WeatherInfo("Seoul", 37.566535, 126.977969, 0));
        mCityList.add(new WeatherInfo("Shanghai", 31.230393, 121.473704, 0));
        mCityList.add(new WeatherInfo("Singapore", 1.352083, 103.819836, 0));
        mCityList.add(new WeatherInfo("Tavoy", 14.08416, 98.201576, 0));
        mCityList.add(new WeatherInfo("Tokyo", 35.689488, 139.691706, 0));
        mCityList.add(new WeatherInfo("Toronto", 43.653226, -79.383184, 0));
        mCityList.add(new WeatherInfo("Vancouver", 49.261226, -123.113927, 0));
        mCityList.add(new WeatherInfo("Washington DC", 38.895112, -77.036366, 0));
//        mCityList.add(new WeatherInfo("Zurich", 47.367347, 8.550003, 0)); // not working
        /*
        mCityList.add(new WeatherInfo("", , 0));
        mCityList.add(new WeatherInfo("", , 0));
        mCityList.add(new WeatherInfo("", , 0));
        */
        return C.SUCCESS;
    }

    @Override
    public void onTerminate() {
        Trace.i(this, "onTerminate");
        super.onTerminate();
    }
    
    /**
     * 
     * @return
     */
    public ArrayList<WeatherInfo> getCityList() {
        return mCityList;
    }
    
    /**
     * 
     */
    public void initWeather() {
        for (WeatherInfo city : mCityList) {
            city.weatherCode = WeatherInfo.UNKNOWN;
            city.condition   = null;
        }
    }

    /**
     * Add user added city list from external database file
     *
     * @param list
     */
    private void addUserCityList(ArrayList<WeatherInfo> list) {
        setDatabaseModifiedTime(UserDatabaseHelper.getModifiedTime());
        
        String filePath = UserDatabaseHelper.getDatabasePath();
        if (filePath == null) {
            return;
        }
        
        
        UserDatabaseHelper dbHelper = new UserDatabaseHelper(this, filePath);
        if (!dbHelper.isExist()) {
            dbHelper.close();
            Trace.i(this, "user.db file is not exist");
            return;
        }
        
        SQLiteDatabase db = dbHelper.getReadableDatabase();
        if (db == null) {
            dbHelper.close();
            Trace.e(this, "Failed to open: " + filePath);
            return;
        }
        
        Cursor cursor = null;
        try {
            cursor = db.rawQuery("SELECT * FROM " + UserDatabaseHelper.TABLE_NAME, null);
        }
        catch (SQLiteException e) {
            Trace.w(this, e.toString());
        }
        
        if (cursor == null) {
            return;
        }

        int indexId        = cursor.getColumnIndex(UserDatabaseHelper.ITEM_ID);
        int indexCityName  = cursor.getColumnIndex(UserDatabaseHelper.ITEM_CITY_NAME);
        int indexLatitude  = cursor.getColumnIndex(UserDatabaseHelper.ITEM_LATITUDE);
        int indexLongitude = cursor.getColumnIndex(UserDatabaseHelper.ITEM_LONGITUDE);
//        int indexAltitude  = cursor.getColumnIndex(UserDatabaseHelper.ITEM_ALTITUDE);
        while (cursor.moveToNext()) {
            int    id    = cursor.getInt(indexId);
            String city  = cursor.getString(indexCityName);
            double lat   = cursor.getDouble(indexLatitude);
            double lon   = cursor.getDouble(indexLongitude);
            double alt   = 0; //cursor.getDouble(indexAltitude);
            
//            Trace.v(this, String.format("%s: %f, %f, %f", city, lat, lon, alt));
            mCityList.add(new WeatherInfo(city, lat, lon, alt, true, id));
        }
        dbHelper.close();
    }
    
    /**
     * Set database modified time
     * 
     * @param time
     */
    public void setDatabaseModifiedTime(long time) {
        mDatabaseModifiedTime = time;
    }
    
    /**
     * Check if database is changed by outside of this application
     * 
     * @return
     */
    public boolean isDatabaseChanged() {
//        Trace.v(this, "file:" + UserDatabaseHelper.getModifiedTime() + " old:" + mDatabaseModifiedTime);
        if (UserDatabaseHelper.getModifiedTime() == mDatabaseModifiedTime) {
            return false;
        }
        
        return true;
    }
}
